<?php
if(!defined('BASE_DIR'))die('Cannot access the file !');
/**
 * -+-----------------------------------------
 * |PHP Framework
 * |Copyright (c) 2010 jinke.[iblue.cc]
 * |E-mail: mejinke@gmail.com
 * |Date: 2010-09-08
 * |Update: 2011-01-06
 * -+-----------------------------------------
 *
 * application 应用程序基础类
 * @author jinke
 */
 class Application extends Base
{

	/**
	 * 应用程序名称
	 * @var string
	 */
	public static $app_name = '';
	
	/**
	 * 应应程序tag标记 [默认hook中使用到]
	 * @var string  
	 */
	public static $app_tag = '';
	
	/**
	 * 应用程序目录文件夹［可选］
	 * @var string
	 */
	public static $app_folder = '';

	/**
	 * 入口文件位置
	 * @var string
	 */
	private static $access_file_name = '';
	

	
	/**
	 * 控制器名称
	 * @var string
	 */
	public static $controller_name = '';

	/**
	 * 动作名称
	 * @var string
	 */
	public static $action_name = '';
	private static $_action_name = '';
	
	/**
	 * 参数列表
	 * @var array
	 */
	public static $args = array();

	/**
	 * 将要运行的控制器对象
	 * @var object
	 */
	private static $controller_object = '';

	/**
	 * 控制器执行结果
	 * @var string
	 */
	private static $action_result = '';

	/**
	 * 路由对象
	 * @var object
	 */
	private static $router = null;
	
	/**
	 * 构子对象
	 * @var object
	 */
	private static $hook = null;

	public function __construct(){}

	/**
	 * 初始化
	 * @access private
	 * @return void
	 */
	private static function init()
	{
		if (!defined('APP_C'))
			self::setControllerName(self::$controller_name);
		if (self::$action_name =='')
			self::$action_name = 'index';
		if (!defined('APP_A'))
			self::setActionName(self::$action_name);
		
		//注册路由对象
		self::$router=Functions::REC('FW_Router','Router');
		self::$router->get();
		//注册钩子
		self::$hook=Functions::REC('FW_Hook','Hook');
		
		self::$controller_name = self::$router->getControllerName();

		self::$_action_name = self::$router->getActionName();
		

		self::$access_file_name = $_SERVER['SCRIPT_NAME'];
			
		//检测是否需要开始DEBUG模式 
		if( (Config::get('step_debug') && Functions::GET('debug')=='true') || Config::get('debug')){
			 ini_set('display_errors', 'on'); 
		}
		
		if (Config::get('sys_error')) {
			 ini_set('display_errors', 'on'); 
		}
	}
	
	public static function setControllerName($controllerName){
		self::$controller_name = $controllerName;
		define('APP_C', $controllerName);
	}
	
	public static function setActionName($actionName){
		self::$action_name = $actionName;
		define('APP_A', $actionName);
	}


	/**
	 * 启动应用程序
	 * @access public
	 * @param	string	$app_name	应用程序名称
	 * @return void
	 */
	public static function run()
	{
		
		self::init();
		//强制必需设置应用程序名称
		if(self::$app_name == '')
			message_error('Run Error','缺少应用程序名称!app_name');

		Debug::$appNames=self::$app_name;

		//设定应用程序最终目录
		if(self::$app_folder == '')
		{
			if (Config::get('app_folder')=='' || Config::get('app_folder')=='/')
				self::$app_folder = self::$app_name;
			else 
				self::$app_folder = Config::get('app_folder').self::$app_name;
		}
				
		//检测应用程序目录是否正确!
		if(!is_dir(BASE_DIR.self::$app_folder))
			self::$app_folder='';

		self::setDefind();
		self::routerlHandle();
		self::setLanguage();
		self::importFuns();
		Functions::REC('FW_User','User');
		Functions::REG('FW_User')->readCookie();

		//记录控制器和动作名称
		Functions::RES('controller_name',self::$controller_name);
		Functions::RES('action_name',self::$_action_name);

		Debug::$appDirs=BASE_DIR.self::$app_folder;
		Debug::$controllers=self::$controller_name.'.php';
		Debug::$actions=self::$_action_name;
		Debug::$argss=self::$router->getArgs();

		//创建需要请求的控制器
		self::$controller_object = C(self::$controller_name);

		if(self::$controller_object)
			self::doAction();
		else
			message_404();

		Functions::RES('run_end_time',Functions::getMicroTime());

		Functions::RES('runTime',sprintf('%.4f',(Functions::REG('run_end_time') - Functions::REG('run_start_time'))).' seconds');

		self::end();

	}


	/**
	 * 设置基本的常量资料
	 * @access private
	 * @return void
	 */
	private static function setDefind()
	{

		/**
		 * 应用程序名称
		 */
		define('APP_NAME',self::$app_name);

		/**
		 * 网站地址
		 */
		define('URL',Config::get('root').Config::get('root_path'));

		/**
		 * 应用程序WEB路径
		 */
		define('APP_PATH',URL.self::$app_name);

		/**
		 * 当前控制器路径
		 */
		define('CE',self::$access_file_name);

		/**
		 * 应用程序物理绝对路径
		 */
		define('APP_DIR',str_replace('//','/',BASE_DIR.self::$app_folder.'/'));

		/**
		 * 全局公共资料目录
		 */
		define('PUBLIC_PATH',URL.'public');

		/**
		 * 当前应用公共资料目录
		 */
		define('APP_PUBLIC',APP_PATH.'/public');

		Functions::REC('FW_View','View');
	}


	/**
	 * 执行action
	 * @access private
	 * @return void
	 */
	private static function doAction()
	{
		self::$hook->run('action_start');
		ob_start();
		self::$controller_object->doAction();
		self::$action_result = ob_get_contents();
		ob_end_clean();
		self::$hook->run('action_end');
	}


	/**
	 * 执行完成 输入资料
	 * @access private
	 * @return void
	 */
	public  static function end()
	{
		session_unset();
		Functions::REG('FW_User')->saveCookie();
		echo self::$action_result;
		self::$controller_object->__destruct();
		if (Config::get('debug'))
			echo Debug::display();
		else
		{
			if(Config::get('step_debug') && isset($_GET['debug']) && $_GET['debug']=='true')
				echo Debug::display();
		}

	}


	/**
	 * 处理用户自定义路由设置
	 * @access private
	 * @return void
	 */
	private static function routerlHandle()
	{
		$tep_array = null ;
		//检测应用是否定义自定义路由
		$tep_array = Functions::getAppConfig(APP_NAME.'.router');
		if ($tep_array===false)
			return;
		if(is_array($tep_array))
		{
			$keys = array_keys($tep_array);
			for($i=0 ; $i<count($tep_array) ; $i++)
			{
				$key = $keys[$i];
				if(self::$action_name == $key)
				{
					self::getCA($key,$tep_array[$key]);
					break;
				}
			}
		}
	}


	/**
	 * 获取最终的控投制器名称及动作Action 名称
	 * @access private
	 * @param string $key	路由名称
	 * @param array	$tep_array	路由配置数组
	 * @return void
	 */
	private static function getCA($key,Array $tep_array)
	{
		if(isset($tep_array['C']))
		{
			self::$controller_name = $tep_array['C'];
			if(isset($tep_array['A']))
				self::$_action_name = $tep_array['A'];
			else
				self::$_action_name = $key ;
			//是否存在参数
			if (isset($tep_array['Args']))
				self::$router->addArgs($tep_array['Args']);

			//重置路由
			self::$router->setController( self::$controller_name ) ;
			self::$router->setAction( self::$_action_name );
		}
		else
		{
			message_error('Run Error','router.conf.php 配置不正确!',message_debug(debug_backtrace()));
		}

	}


	/**
	 * 加截用户自定义函数库
	 * @access private
	 * @return void
	 */
	private static function importFuns()
	{
		//获取欲加载的函数列表
		$funs = Config::get('functions');

		if(isset($funs) && is_array($funs))
		{
			for($i=0;$i<count($funs);$i++)
			{
				$file = EXTEND_FUN_DIR.$funs[$i];
				if(!empty($funs[$i]) && is_file($file))
					require_once $file;
			}
		}
	}


	/**
	 * 装载语言包
	 * 使用说明：
	 * ========程序中调用==============
	 * 全局语言包：$this->lang_comm_msg; (注：lang_comm_ 为固定写法)
	 * 应用程序全局语方包：$this->lang_app_msg;  (注：lang_app_ 为固定写法)
	 * 当前控制器语言包：$this->lang_msg
     *
	 * ========模板中调用==============
	 * 全局语言包：{$lang.comm.msg} 
	 * 当前应用程序全局语言包：{$lang.app.msg}
	 * 当前控制器语言包：{$lang.msg}
	 * 
	 * @access private
	 * @return void
	 */
	private static function setLanguage()
	{
		$lang_folder = Config::get('language');
		if ($lang_folder == '')
			return;
		$lang_dir = BASE_DIR.'language/'.$lang_folder;
		if(is_dir($lang_dir))
		{

			//当前控制器 例：/language/default/home/user.lang.php
			$file = $lang_dir.'/'.APP_NAME.'/'.self::$router->getController().'.lang.php';
			$lang = is_file($file)?require_once $file:array();

			//全局公共 例：/language/default/common.lang.php
			$file = $lang_dir.'/common.lang.php';
			$lang['comm'] = is_file($file)?require_once $file:array();

			//应用公共 例：/language/default/home/common.lang.php
			$file = $lang_dir.'/'.APP_NAME.'/common.lang.php';
			$lang['app'] = is_file($file)?require_once $file:array();


			//设置语言包
			self::$controller_object->lang = $lang;
			Functions::RES('_lang',$lang);
		}
	}

}
?>
